A GitHub Action Template for a dotnet NuGet package
I’ve recently been using GitHub Actions a lot more heavily and as you know, I have a lot of GitHub repositories that become NuGet packages. I have been using AppVeyor and have had no issues with it. The only reasons I’m switching to GitHub actions is 1) to learn new things and 2) to be able to have the pipeline and source all in one site.
This GitHub action template will generate a NuGet package for any repository that is setup as a Microlibrary (See We are already in the age of Microlibraries).
Requirements to use the DotNet Nuget Package Workflow
This template is easy to use.
Requirements
- It is for a microlibrary.
A microlibrary is basically a repository with only one dll project. In C#, that means a repo is setup with only one Visual Studio solution that usually has two projects:- The DLL project
- The unit test project (The template will fail without a unit test project.)
- The template assumes you have everything in a directory called src.
- The solution is in the src directory.
- There is a nuget.config in the src directory
- The DLL project is configured to build a NuGet package on Release builds.
Note: Add this to your csproj file:<GeneratePackageOnBuild Condition="'$(Configuration)'=='Release'">True</GeneratePackageOnBuild>
- The GitHub actions template is not in the src directory, but in this directory
.github\workflows - This template publishes to NuGet.org and you must create a key in NuGet.org, then in GitHub repo settings, make that key a secret called:
NUGET_API_KEY
Options
Not everything is required.
- Versioning is created using the Build and typed in versions.
- Changing the version is easy. Just update the yml file.
- Want a new version to start at 0? (For example, you are at 1.1.25 and you want to go to 1.2.0)
- Simply set the base offset found below in the ‘# Get build number’ section of the template to subtract the build count.
For example, if you are on build 121 and your next build will be 122, set the value to -122.
- Simply set the base offset found below in the ‘# Get build number’ section of the template to subtract the build count.
- Code Coverage
- You can enforce code coverage and get a nice report in pull requests for the provided coverage.
- Chaning the code coverage percentage requirement is easy.
- Disabling code coverage is an option.
- The code coverage tool used doesn’t work with windows-latest. Notice the yml file says:
runs-on: ubuntu-latest
However, you can run on windows-latest, and this template will simply skip those lines.
- You can enforce code coverage and get a nice report in pull requests for the provided coverage.
- There is an option for you to have a vNext branch that will build prerelease versions.
If you want your vNext branch to be named something else such as future or current then you can just find and replace vNext with the desired branch name. - You can change the version of dotnet:
dotnet-version: [ ‘8.0.x’ ]
# Created by Jared Barneck (Rhyous). # Used to build dotnet microlibraries and publish them to NuGet name: CI - Main # Controls when the workflow will run on: # Triggers the workflow on push events to the "master" or "vNext" branches push: branches: [ "master", "vNext" ] paths-ignore: - '**.md' - '**.yml' - '**/*.Tests/**' - '**/.editorconfig' - '**/.editorconfig' - '**/.gitignore' - '**/docs/**' - '**/NuGet.Config' - '.gitignore' # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" build: # The type of runner that the job will run on runs-on: ubuntu-latest defaults: run: # There should only be one solution file (.sln) and it should be in the src dir. working-directory: src strategy: matrix: dotnet-version: [ '8.0.x' ] # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3 # Get dotnet setup and ready to work - name: Setup .NET Core SDK ${{ matrix.dotnet-version }} uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ matrix.dotnet-version }} # Restore nuget packages - name: Restoring NuGet packages run: dotnet restore # Get build number - name: Get Build Number with base offset uses: mlilback/build-number@v1 with: base: -8 run-id: ${{github.run_number}} # Build - Main - name: Build source if: github.ref == 'refs/heads/master' run: dotnet build --configuration Release --no-restore -p:AssemblyVersion=1.3.0 -p:FileVersion=1.3.${{env.BUILD_NUMBER}} -p:Version=1.3.${{env.BUILD_NUMBER}} # Build - vNext - name: Build source if: github.ref == 'refs/heads/vNext' run: dotnet build --configuration Release --no-restore -p:AssemblyVersion=2.0.0 -p:FileVersion=2.0.${{env.BUILD_NUMBER}} -p:Version=2.0.${{env.BUILD_NUMBER}} --version-suffix alpha # Run Unit Tests # Add coverlet.collector nuget package to test project - 'dotnet add &amp;lt;TestProject.cspoj&amp;gt; package coverlet - name: Run Tests run: dotnet test --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --logger trx --results-directory coverage --filter TestCategory!=SkipCI # Install ReportGenerator - name: Install ReportGenerator run: dotnet tool install -g dotnet-reportgenerator-globaltool # Run ReportGenerator - name: Run ReportGenerator run: reportgenerator -reports:./coverage/*/coverage.cobertura.xml -targetdir:coveragereport -reportType:Cobertura # Code Coverage - name: Code Coverage Report if: runner.os == 'Linux' uses: irongut/CodeCoverageSummary@v1.3.0 with: filename: '**/Cobertura.xml' badge: true fail_below_min: true format: markdown hide_branch_rate: false hide_complexity: true indicators: true output: both thresholds: '60 80' - name: Add Coverage PR Comment uses: marocchino/sticky-pull-request-comment@v2 if: runner.os == 'Linux' &amp;amp;&amp;amp; github.event_name == 'pull_request' with: recreate: true path: code-coverage-results.md # Publish NuGet - name: Publish the NuGet package if: ${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch') &amp;amp;&amp;amp; github.ref == 'refs/heads/master' }} run: dotnet nuget push "**/*.nupkg" --source "https://api.nuget.org/v3/index.json" --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate